import wx

class MyFrame(wx.Frame):
    def __init__(self, parent):
        # 初始化主窗口
        wx.Frame.__init__(self, parent, id=wx.ID_ANY, title="Calculator", pos=wx.DefaultPosition,
                          size=wx.Size(400, 300), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)

        # 设置窗口的最小尺寸
        self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)

        # 创建一个垂直布局管理器
        bSizer21 = wx.BoxSizer(wx.VERTICAL)

        # 创建一个文本框用于显示计算表达式和结果 ID_ANY表示使用默认ID
        self.m_textCtrl1 = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size(330, -1), 0)

        # 将文本框添加到布局管理器中，并设置边距和扩展属性
        bSizer21.Add(self.m_textCtrl1, 0, wx.ALL | wx.EXPAND, 5)

        # 定义按钮的布局，每个按钮是一个元组，包含标签和值
        buttons = [
            ('1', 1), ('2', 2), ('3', 3), ('+', '+'),
            ('4', 4), ('5', 5), ('6', 6), ('-', '-'),
            ('7', 7), ('8', 8), ('9', 9), ('*', '*'),
            ('0', 0), ('AC', 'AC'), ('/', '/'), ('=', '=')
        ]

        # 创建一个 4x4 的网格布局管理器
        grid_sizer = wx.GridSizer(4, 4, 10, 10)

        # 遍历按钮定义，创建按钮并添加到网格布局中
        for label, value in buttons:
            button = wx.Button(self, wx.ID_ANY, label, wx.DefaultPosition, wx.DefaultSize, 0)
            # 绑定按钮的点击事件到事件处理函数
            button.Bind(wx.EVT_BUTTON, lambda evt, val=value: self.on_button_click(evt, val))
            # 将按钮添加到网格布局中，并设置扩展属性
            grid_sizer.Add(button, 0, wx.EXPAND)

        # 将网格布局添加到主布局管理器中，并设置扩展属性
        bSizer21.Add(grid_sizer, 1, wx.EXPAND, 5)

        # 设置窗口的布局管理器
        self.SetSizer(bSizer21)
        # 应用布局
        self.Layout()
        # 将窗口居中显示
        self.Centre(wx.BOTH)

        # 初始化计算表达式为空字符串
        self.expression = ""

    def on_button_click(self, event, value):
        # 处理按钮点击事件
        if value == 'AC':
            # 清除表达式并清空文本框
            self.expression = ""
            self.m_textCtrl1.SetValue("")
        elif value == '=':
            # 计算表达式的结果
            try:
                result = eval(self.expression)
                self.expression = str(result)
                self.m_textCtrl1.SetValue(self.expression)

            except Exception as e:
                # 如果表达式无效，显示错误信息
                self.m_textCtrl1.SetValue("Error")
        else:
            # 将按钮的值添加到表达式中，并更新文本框显示
            self.expression += str(value)
            self.m_textCtrl1.SetValue(self.expression)


# 创建应用程序实例
app = wx.App(False)
# 创建主窗口实例
frame = MyFrame(None)
# 显示主窗口
frame.Show(True)
# 进入应用程序主循环
app.MainLoop()
